package tenumn.energytech.registrys.machine;

import io.github.uicdb.liba.api.util.LazyUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluids;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tenumn.energytech.registrys.CapabilitiesRegistry;
import tenumn.energytech.registrys.FluidRegistry;
import tenumn.energytech.registrys.capability.CapabilityHeart;
import tenumn.energytech.registrys.capability.GasTank;

import java.util.Set;

public class SteamBoilerBlockEntity extends MachineBlockEntity {
    private final FluidTank fluidTank = new FluidTank(500000, fluidStack -> fluidStack.getFluid().isSame(Fluids.WATER));
    private final GasTank gasTank = new GasTank(500000, fluidStack -> fluidStack.getFluid().isSame(FluidRegistry.steam.get()));
    private final CapabilityHeart heart=new CapabilityHeart(0,0,Float.MAX_VALUE);
    public SteamBoilerBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
        super(pType, pWorldPosition, pBlockState);
    }

    @NotNull
    @Override
    public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
            return LazyOptional.of(() -> fluidTank).cast();
        if (cap == CapabilitiesRegistry.GAS_CAPABILITY&&side!=null)
            if(getGasDirections().contains(side))
            return LazyOptional.of(() -> gasTank).cast();
        if(cap==CapabilitiesRegistry.HEART_CAPABILITY){
            return LazyOptional.of(()->heart).cast();
        }
        return super.getCapability(cap, side);
    }

    @Override
    protected void saveAdditional(CompoundTag pTag) {
        pTag.put("Fluid", fluidTank.writeToNBT(new CompoundTag()));
        pTag.put("Gas", gasTank.writeToNBT(new CompoundTag()));
        pTag.put("Heart",heart.serializeNBT());
        super.saveAdditional(pTag);
    }

    @Override
    public void load(CompoundTag pTag) {
        fluidTank.readFromNBT(pTag.getCompound("Fluid"));
        gasTank.readFromNBT(pTag.getCompound("Gas"));
        heart.deserializeNBT(pTag.getCompound("Heart"));
        super.load(pTag);
    }
    private final Set<Direction> mGasDirections=Set.of(Direction.values());
    protected Set<Direction> getGasDirections(){
        return mGasDirections;
    }
    @Override
    public void tick() {
        if (level instanceof ServerLevel serverLevel) {
            fluidTank.fill(new FluidStack(Fluids.WATER, Integer.MAX_VALUE), IFluidHandler.FluidAction.EXECUTE);
            if (!gasTank.isEmpty()) {
                for(Direction direction:getGasDirections()) {
                    BlockEntity blockEntity = serverLevel.getBlockEntity(getBlockPos().relative(direction));
                    if (blockEntity != null)
                        blockEntity.getCapability(CapabilitiesRegistry.GAS_CAPABILITY, direction.getOpposite())
                                .ifPresent(gas -> {
                                    LazyUtil.translateTank(150, gasTank.getFluid().getFluid(), gasTank, gas, 10);
                                });
                }
            }
            float temp=heart.getTemperature();
            if(fluidTank.isEmpty()){//高温爆炸
                if(temp>500)serverLevel.explode(null,getBlockPos().getX(),getBlockPos().getY(),getBlockPos().getZ(),2,true, Explosion.BlockInteraction.BREAK);
            }
            else {
                if(temp>0) {
                    LazyUtil.translateTank(100, FluidRegistry.steam.get(), fluidTank, gasTank, 1);
                    heart.coolDown(16,false);
                }
            }
            level.blockEntityChanged(getBlockPos());
        }
    }
}
